<!--
    by: yuanbiao 2020年10月22日
    name: x-tree
    notes:
-->
<template>
  <div :class="[prefixCls,`${prefixCls}-${size}`]">
    <div :class="`${prefixCls}__head`">
      <span :class="`${prefixCls}__head_icon`">
        <i class="xvu-iconfont xvu-circle"></i>
      </span>
      <span :class="`${prefixCls}__head_line`"></span>
    </div>
    <div :class="`${prefixCls}__body`">
      <x-tree-node
        v-for="(item, i) in stateTree" :key="i"
        :data="item"
        :level="0"
        :children-key="childrenKey"
      ></x-tree-node>
      <div :class="`${prefixCls}__body_empty`">
        {{ stateTree.length ? '' : emptyText }}
      </div>
    </div>
    <div :class="`${prefixCls}__foot`">
      <span :class="`${prefixCls}__foot_line`"></span>
      <span :class="`${prefixCls}__foot_icon`">
        <i class="xvu-iconfont xvu-triangle-down"></i>
        <!-- <i v-if="滚动条不在底部" class="xvu-iconfont xvu-triangle-down"></i>
        <i v-else class="xvu-iconfont xvu-circle"></i> -->
      </span>
    </div>
  </div>
</template>

<script>
import xTreeNode from './node.vue'
const prefixCls = 'x-tree'
export default {
  name: 'x-tree',
  components: {
    xTreeNode
  },
  props: {
    data: {
      type: Array,
      default () {
        return []
      }
    },
    size: {
      type: String,
      default: 'default' // default|large|small
    },
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    childrenKey: {
      type: String,
      default: 'children'
    }
  },
  data() {
    return {
      prefixCls: prefixCls,
      stateTree: this.data,
      flatState: []
    }
  },
  watch: {
    data: {
      deep: true,
      handler () {
        this.stateTree = this.data
        this.flatState = this.compileFlatState()
      }
    }
  },
  methods: {
    compileFlatState () { // so we have always a relation parent/children of each node
      let keyCounter = 0
      let childrenKey = this.childrenKey
      const flatTree = []
      function flattenChildren(node, parent) {
        node.nodeKey = keyCounter++
        flatTree[node.nodeKey] = { node: node, nodeKey: node.nodeKey }
        if (typeof parent !== 'undefined') {
          flatTree[node.nodeKey].parent = parent.nodeKey
          flatTree[parent.nodeKey][childrenKey].push(node.nodeKey)
        }
        if (node[childrenKey]) {
          flatTree[node.nodeKey][childrenKey] = []
          node[childrenKey].forEach(child => flattenChildren(child, node))
        }
      }
      this.stateTree.forEach(rootNode => {
        flattenChildren(rootNode)
      })
      return flatTree
    },
    getSelectedNodes () {
      /* public API */
      return this.flatState.filter(obj => obj.node.selected).map(obj => obj.node)
    },
    handleSelect (nodeKey) {
      const node = this.flatState[nodeKey].node
      const currentSelectedKey = this.flatState.findIndex(obj => obj.node.selected)
      if (currentSelectedKey >= 0 && currentSelectedKey !== nodeKey) this.$set(this.flatState[currentSelectedKey].node, 'selected', false)
      this.$set(node, 'selected', !node.selected)
      this.$emit('on-select-change', this.getSelectedNodes(), node)
    }
  },
  created () {
    this.flatState = this.compileFlatState()
  },
  mounted () {
    this.$on('on-selected', this.handleSelect)
    this.$on('toggle-expand', node => this.$emit('on-toggle-expand', node))
  }
}
</script>
